{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ef430b55",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:05:43.630705Z",
     "start_time": "2024-09-12T01:05:43.612715Z"
    }
   },
   "outputs": [],
   "source": [
    "# To support both python 2 and python 3\n",
    "from __future__ import division, print_function, unicode_literals\n",
    "\n",
    "# Common imports\n",
    "import numpy as np\n",
    "import os\n",
    "\n",
    "# to make this notebook's output stable across runs\n",
    "np.random.seed(42)\n",
    "\n",
    "# To plot pretty figures\n",
    "%matplotlib inline \n",
    "#内嵌图片显示\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "mpl.rc('axes', labelsize=14)\n",
    "mpl.rc('xtick', labelsize=12)\n",
    "mpl.rc('ytick', labelsize=12)\n",
    "\n",
    "plt.rcParams['font.sans-serif'] = 'SimHei'\n",
    "plt.rcParams['axes.unicode_minus'] = False\n",
    "\n",
    "# Where to save the figures\n",
    "PROJECT_ROOT_DIR = \".\"\n",
    "CHAPTER_ID = \"fundamentals\"\n",
    "\n",
    "def save_fig(fig_id, tight_layout=True):\n",
    "    path = os.path.join(PROJECT_ROOT_DIR, \"images\", CHAPTER_ID, fig_id + \".png\")\n",
    "    print(\"Saving figure\", fig_id)\n",
    "    if tight_layout:\n",
    "        plt.tight_layout()\n",
    "    plt.savefig(path, format='png', dpi=300)\n",
    "\n",
    "# Ignore useless warnings (see SciPy issue #5998)\n",
    "import warnings\n",
    "warnings.filterwarnings(action=\"ignore\", message=\"^internal gelsd\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "b0648512",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:13:51.909408Z",
     "start_time": "2024-09-12T01:13:51.524457Z"
    }
   },
   "outputs": [],
   "source": [
    "import pandas as pd"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "413baad7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:24:15.562620Z",
     "start_time": "2024-09-12T01:24:15.551610Z"
    }
   },
   "outputs": [],
   "source": [
    "datapath = os.path.join(\"datasets\", \"lifesat\", \"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "ddae97e3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:28:34.882974Z",
     "start_time": "2024-09-12T01:28:34.858036Z"
    }
   },
   "outputs": [
    {
     "ename": "FileNotFoundError",
     "evalue": "[Errno 2] No such file or directory: 'datasets\\\\lifesat\\\\oecd_bli_2015.csv'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mFileNotFoundError\u001b[0m                         Traceback (most recent call last)",
      "Cell \u001b[1;32mIn[7], line 1\u001b[0m\n\u001b[1;32m----> 1\u001b[0m oecd_bli \u001b[38;5;241m=\u001b[39m pd\u001b[38;5;241m.\u001b[39mread_csv(datapath \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124moecd_bli_2015.csv\u001b[39m\u001b[38;5;124m'\u001b[39m, thousands\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m,\u001b[39m\u001b[38;5;124m'\u001b[39m)\n",
      "File \u001b[1;32mC:\\ProgramData\\anaconda3\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:1026\u001b[0m, in \u001b[0;36mread_csv\u001b[1;34m(filepath_or_buffer, sep, delimiter, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skipinitialspace, skiprows, skipfooter, nrows, na_values, keep_default_na, na_filter, verbose, skip_blank_lines, parse_dates, infer_datetime_format, keep_date_col, date_parser, date_format, dayfirst, cache_dates, iterator, chunksize, compression, thousands, decimal, lineterminator, quotechar, quoting, doublequote, escapechar, comment, encoding, encoding_errors, dialect, on_bad_lines, delim_whitespace, low_memory, memory_map, float_precision, storage_options, dtype_backend)\u001b[0m\n\u001b[0;32m   1013\u001b[0m kwds_defaults \u001b[38;5;241m=\u001b[39m _refine_defaults_read(\n\u001b[0;32m   1014\u001b[0m     dialect,\n\u001b[0;32m   1015\u001b[0m     delimiter,\n\u001b[1;32m   (...)\u001b[0m\n\u001b[0;32m   1022\u001b[0m     dtype_backend\u001b[38;5;241m=\u001b[39mdtype_backend,\n\u001b[0;32m   1023\u001b[0m )\n\u001b[0;32m   1024\u001b[0m kwds\u001b[38;5;241m.\u001b[39mupdate(kwds_defaults)\n\u001b[1;32m-> 1026\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m _read(filepath_or_buffer, kwds)\n",
      "File \u001b[1;32mC:\\ProgramData\\anaconda3\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:620\u001b[0m, in \u001b[0;36m_read\u001b[1;34m(filepath_or_buffer, kwds)\u001b[0m\n\u001b[0;32m    617\u001b[0m _validate_names(kwds\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnames\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m))\n\u001b[0;32m    619\u001b[0m \u001b[38;5;66;03m# Create the parser.\u001b[39;00m\n\u001b[1;32m--> 620\u001b[0m parser \u001b[38;5;241m=\u001b[39m TextFileReader(filepath_or_buffer, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwds)\n\u001b[0;32m    622\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m chunksize \u001b[38;5;129;01mor\u001b[39;00m iterator:\n\u001b[0;32m    623\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m parser\n",
      "File \u001b[1;32mC:\\ProgramData\\anaconda3\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:1620\u001b[0m, in \u001b[0;36mTextFileReader.__init__\u001b[1;34m(self, f, engine, **kwds)\u001b[0m\n\u001b[0;32m   1617\u001b[0m     \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moptions[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhas_index_names\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m=\u001b[39m kwds[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mhas_index_names\u001b[39m\u001b[38;5;124m\"\u001b[39m]\n\u001b[0;32m   1619\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles: IOHandles \u001b[38;5;241m|\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m-> 1620\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_engine \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_make_engine(f, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mengine)\n",
      "File \u001b[1;32mC:\\ProgramData\\anaconda3\\Lib\\site-packages\\pandas\\io\\parsers\\readers.py:1880\u001b[0m, in \u001b[0;36mTextFileReader._make_engine\u001b[1;34m(self, f, engine)\u001b[0m\n\u001b[0;32m   1878\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m mode:\n\u001b[0;32m   1879\u001b[0m         mode \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m-> 1880\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles \u001b[38;5;241m=\u001b[39m get_handle(\n\u001b[0;32m   1881\u001b[0m     f,\n\u001b[0;32m   1882\u001b[0m     mode,\n\u001b[0;32m   1883\u001b[0m     encoding\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moptions\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mencoding\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m),\n\u001b[0;32m   1884\u001b[0m     compression\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moptions\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcompression\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m),\n\u001b[0;32m   1885\u001b[0m     memory_map\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moptions\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmemory_map\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mFalse\u001b[39;00m),\n\u001b[0;32m   1886\u001b[0m     is_text\u001b[38;5;241m=\u001b[39mis_text,\n\u001b[0;32m   1887\u001b[0m     errors\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moptions\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mencoding_errors\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mstrict\u001b[39m\u001b[38;5;124m\"\u001b[39m),\n\u001b[0;32m   1888\u001b[0m     storage_options\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moptions\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mstorage_options\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m),\n\u001b[0;32m   1889\u001b[0m )\n\u001b[0;32m   1890\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m   1891\u001b[0m f \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mhandles\u001b[38;5;241m.\u001b[39mhandle\n",
      "File \u001b[1;32mC:\\ProgramData\\anaconda3\\Lib\\site-packages\\pandas\\io\\common.py:873\u001b[0m, in \u001b[0;36mget_handle\u001b[1;34m(path_or_buf, mode, encoding, compression, memory_map, is_text, errors, storage_options)\u001b[0m\n\u001b[0;32m    868\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(handle, \u001b[38;5;28mstr\u001b[39m):\n\u001b[0;32m    869\u001b[0m     \u001b[38;5;66;03m# Check whether the filename is to be opened in binary mode.\u001b[39;00m\n\u001b[0;32m    870\u001b[0m     \u001b[38;5;66;03m# Binary mode does not support 'encoding' and 'newline'.\u001b[39;00m\n\u001b[0;32m    871\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m ioargs\u001b[38;5;241m.\u001b[39mencoding \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m ioargs\u001b[38;5;241m.\u001b[39mmode:\n\u001b[0;32m    872\u001b[0m         \u001b[38;5;66;03m# Encoding\u001b[39;00m\n\u001b[1;32m--> 873\u001b[0m         handle \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mopen\u001b[39m(\n\u001b[0;32m    874\u001b[0m             handle,\n\u001b[0;32m    875\u001b[0m             ioargs\u001b[38;5;241m.\u001b[39mmode,\n\u001b[0;32m    876\u001b[0m             encoding\u001b[38;5;241m=\u001b[39mioargs\u001b[38;5;241m.\u001b[39mencoding,\n\u001b[0;32m    877\u001b[0m             errors\u001b[38;5;241m=\u001b[39merrors,\n\u001b[0;32m    878\u001b[0m             newline\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m    879\u001b[0m         )\n\u001b[0;32m    880\u001b[0m     \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m    881\u001b[0m         \u001b[38;5;66;03m# Binary mode\u001b[39;00m\n\u001b[0;32m    882\u001b[0m         handle \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mopen\u001b[39m(handle, ioargs\u001b[38;5;241m.\u001b[39mmode)\n",
      "\u001b[1;31mFileNotFoundError\u001b[0m: [Errno 2] No such file or directory: 'datasets\\\\lifesat\\\\oecd_bli_2015.csv'"
     ]
    }
   ],
   "source": [
    "oecd_bli = pd.read_csv(datapath + 'oecd_bli_2015.csv', thousands=',')\n",
    "# gdp_per_capita = pd.read_excel(datapath + 'gdp_per_capita.csv', thousands=',')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4b3f2139",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:29:07.312557Z",
     "start_time": "2024-09-12T01:29:07.273666Z"
    }
   },
   "outputs": [],
   "source": [
    "oecd_bli.info()\n",
    "oecd_bli.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "921db5ed",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:32:04.592013Z",
     "start_time": "2024-09-12T01:32:04.585032Z"
    }
   },
   "outputs": [],
   "source": [
    "oecd_bli['INEQUALITY'].value_counts()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d456eb0b",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:34:13.158673Z",
     "start_time": "2024-09-12T01:34:13.128754Z"
    }
   },
   "outputs": [],
   "source": [
    "oecd_bli = oecd_bli[oecd_bli['INEQUALITY'] == 'TOT']\n",
    "oecd_bli"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e15bd1c1",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:40:39.812737Z",
     "start_time": "2024-09-12T01:40:39.793788Z"
    }
   },
   "outputs": [],
   "source": [
    "oecd_bli = oecd_bli.pivot(index='Country', columns='Indicator', values='Value')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "db1f58e3",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:40:42.209646Z",
     "start_time": "2024-09-12T01:40:42.194176Z"
    }
   },
   "outputs": [],
   "source": [
    "oecd_bli.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "5f253d2f",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:42:01.110611Z",
     "start_time": "2024-09-12T01:42:01.105624Z"
    }
   },
   "outputs": [],
   "source": [
    "oecd_bli.rename(columns={'Life satisfaction':'生活满意度'}, inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "44e2cbb4",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:42:17.842283Z",
     "start_time": "2024-09-12T01:42:17.826327Z"
    }
   },
   "outputs": [],
   "source": [
    "oecd_bli.columns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c3eabbe",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:54:13.607279Z",
     "start_time": "2024-09-12T01:54:13.584613Z"
    }
   },
   "outputs": [],
   "source": [
    "gdp_per_capita = pd.read_csv(datapath + 'gdp_per_capita.csv', thousands=',', header = None,sep=\"\\t+\", engine='python')\n",
    "gdp_per_capita"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2ac0e970",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:55:54.428372Z",
     "start_time": "2024-09-12T01:55:54.414409Z"
    }
   },
   "outputs": [],
   "source": [
    "gdp_per_capita.rename(columns={'D':'人均GDP'}, inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "cac4da82",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T02:00:10.810492Z",
     "start_time": "2024-09-12T02:00:10.753644Z"
    }
   },
   "outputs": [],
   "source": [
    "left = pd.DataFrame({''Life satisfaction':'生活满意度''})oecd_bli['INEQUALITY']\n",
    "sample_data = pd.DataFrame([oecd_bli, gdp_per_capita], axis=1, )\n",
    "sample_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f87552c7",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-09-12T01:59:40.509231Z",
     "start_time": "2024-09-12T01:59:40.202288Z"
    }
   },
   "outputs": [],
   "source": [
    "sample_data.plot(kind='scatter', x=\"人均GDP\", y='生活满意度', figsize=(5,3))\n",
    "plt.axis([0, 60000, 0, 10])\n",
    "position_text = {\n",
    "    \"Hungary\": (5000, 1),\n",
    "    \"Korea\": (18000, 1.7),\n",
    "    \"France\": (29000, 2.4),\n",
    "    \"Australia\": (40000, 3.0),\n",
    "    \"United States\": (52000, 3.8),\n",
    "}\n",
    "for country, pos_text in position_text.items():\n",
    "    pos_data_x, pos_data_y = sample_data.loc[country]\n",
    "    if country == \"United States\":  country = \"美国\"\n",
    "    if country == \"Hungary\": country = \"匈牙利\"\n",
    "    if country == \"Korea\": country = \"韩国\" \n",
    "    if country == \"France\": country = \"法国\" \n",
    "    if country == \"Australia\": country = \"澳大利亚\" \n",
    "    plt.annotate(country, xy=(pos_data_x, pos_data_y), xytext=pos_text,\n",
    "            arrowprops=dict(facecolor='black', width=0.5, shrink=0.1, headwidth=5))\n",
    "    plt.plot(pos_data_x, pos_data_y, \"ro\")\n",
    "save_fig('money_happy_scatterplot')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "8f733894",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "sample_data.plot(kind='scatter', x=\"人均GDP\", y='生活满意度', figsize=(5,3))\n",
    "plt.axis([0, 60000, 0, 10])\n",
    "X=np.linspace(0, 60000, 1000)\n",
    "plt.plot(X, 2*X/100000, \"r\")\n",
    "plt.text(40000, 2.7, r\"$\\theta_0 = 0$\", fontsize=14, color=\"r\")\n",
    "plt.text(40000, 1.8, r\"$\\theta_1 = 2 \\times 10^{-5}$\", fontsize=14, color=\"r\")\n",
    "plt.plot(X, 8 - 5*X/100000, \"g\")\n",
    "plt.text(5000, 9.1, r\"$\\theta_0 = 8$\", fontsize=14, color=\"g\")\n",
    "plt.text(5000, 8.2, r\"$\\theta_1 = -5 \\times 10^{-5}$\", fontsize=14, color=\"g\")\n",
    "plt.plot(X, 4 + 5*X/100000, \"b\")\n",
    "plt.text(5000, 3.5, r\"$\\theta_0 = 4$\", fontsize=14, color=\"b\")\n",
    "plt.text(5000, 2.6, r\"$\\theta_1 = 5 \\times 10^{-5}$\", fontsize=14, color=\"b\")\n",
    "save_fig('tweaking_model_params_plot')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c72fe7fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_data.plot(kind='scatter', x=\"人均GDP\", y='生活满意度', figsize=(5,3))\n",
    "plt.axis([0, 60000, 0, 10])\n",
    "X=np.linspace(0, 60000, 1000)\n",
    "plt.plot(X, t0 + t1*X, \"b\")\n",
    "plt.text(5000, 3.1, r\"$\\theta_0 = 4.85$\", fontsize=14, color=\"b\")\n",
    "plt.text(5000, 2.2, r\"$\\theta_1 = 4.91 \\times 10^{-5}$\", fontsize=14, color=\"b\")\n",
    "save_fig('best_fit_model_plot')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e671d53e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 可视化\n",
    "sample_data.plot(kind='scatter', x=\"人均GDP\", y='生活满意度', figsize=(5,3), s=1)\n",
    "X=np.linspace(0, 60000, 1000)\n",
    "plt.plot(X, t0 + t1*X, \"b\")\n",
    "plt.axis([0, 60000, 0, 10])\n",
    "plt.text(5000, 7.5, r\"$\\theta_0 = 4.85$\", fontsize=14, color=\"b\")\n",
    "plt.text(5000, 6.6, r\"$\\theta_1 = 4.91 \\times 10^{-5}$\", fontsize=14, color=\"b\")\n",
    "plt.plot([7990, 7990], [0, China_predicted_life_satisfaction], \"r--\")\n",
    "plt.text(9500, 4.5, r\"Prediction = 5.24\", fontsize=14, color=\"b\")\n",
    "plt.plot(7990, China_predicted_life_satisfaction, \"ro\")\n",
    "save_fig('China_prediction_plot')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c169f648",
   "metadata": {},
   "outputs": [],
   "source": [
    "def prepare_country_stats(oecd_bli, gdp_per_capita):\n",
    "    oecd_bli = oecd_bli[oecd_bli[\"INEQUALITY\"]==\"TOT\"]\n",
    "    oecd_bli = oecd_bli.pivot(index=\"Country\", columns=\"Indicator\", values=\"Value\")\n",
    "    oecd_bli.rename(columns={'Life satisfaction':'生活满意度'}, inplace=True)\n",
    "    gdp_per_capita.rename(columns={\"2015\": \"人均GDP\"}, inplace=True)\n",
    "    gdp_per_capita.set_index(\"Country\", inplace=True)\n",
    "    full_country_stats = pd.merge(left=oecd_bli, right=gdp_per_capita,\n",
    "                                  left_index=True, right_index=True)\n",
    "    full_country_stats.sort_values(by=\"人均GDP\", inplace=True)\n",
    "    remove_indices = [0, 1, 6, 8, 33, 34, 35]\n",
    "    keep_indices = list(set(range(36)) - set(remove_indices))\n",
    "    return full_country_stats[[\"人均GDP\", '生活满意度']].iloc[keep_indices]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ab1e756a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Code example\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "import sklearn.linear_model\n",
    "\n",
    "# Load the data\n",
    "oecd_bli = pd.read_csv(datapath + \"oecd_bli_2015.csv\", thousands=',')\n",
    "gdp_per_capita = pd.read_csv(datapath + \"gdp_per_capita.csv\",thousands=',',delimiter='\\t',\n",
    "                             encoding='latin1', na_values=\"n/a\")\n",
    "\n",
    "# Prepare the data\n",
    "country_stats = prepare_country_stats(oecd_bli, gdp_per_capita)\n",
    "X = np.c_[country_stats[\"人均GDP\"]]\n",
    "y = np.c_[country_stats[\"生活满意度\"]]\n",
    "\n",
    "# Visualize the data\n",
    "country_stats.plot(kind='scatter', x=\"人均GDP\", y='生活满意度')\n",
    "\n",
    "# Select a linear model\n",
    "model = sklearn.linear_model.LinearRegression()\n",
    "\n",
    "# Train the model\n",
    "model.fit(X, y)\n",
    "\n",
    "# Make a prediction for China\n",
    "X_new = [[7990]]  # China' GDP per capita\n",
    "China_predicted_life_satisfaction = model.predict(X_new)\n",
    "print(China_predicted_life_satisfaction) # outputs [[5.24548521]]\n",
    "plt.plot(X_new, China_predicted_life_satisfaction, \"ro\")\n",
    "plt.annotate('中国', xy=(7990,China_predicted_life_satisfaction), xytext=(13000,5.1),\n",
    "             arrowprops=dict(facecolor='black', width=0.5, shrink=0.1, headwidth=5))\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "edee0f7e",
   "metadata": {},
   "outputs": [],
   "source": [
    "position_text2 = {\n",
    "    \"Brazil\": (1000, 9.0),\n",
    "    \"Mexico\": (11000, 9.0),\n",
    "    \"Chile\": (25000, 9.0),\n",
    "    \"Czech Republic\": (35000, 9.0),\n",
    "    \"Norway\": (60000, 3),\n",
    "    \"Switzerland\": (72000, 3.0),\n",
    "    \"Luxembourg\": (90000, 3.0),\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0851097e",
   "metadata": {},
   "outputs": [],
   "source": [
    "sample_data.plot(kind='scatter', x=\"人均GDP\", y='生活满意度', figsize=(8,3))\n",
    "plt.axis([0, 110000, 0, 10])\n",
    "\n",
    "for country, pos_text in position_text2.items():\n",
    "    pos_data_x, pos_data_y = missing_data.loc[country]\n",
    "    if country == \"Brazil\":  country = \"巴西\"\n",
    "    if country == \"Mexico\": country = \"墨西哥\"\n",
    "    if country == \"Chile\": country = \"智利\" \n",
    "    if country == \"Czech Republic\": country = \"捷克\" \n",
    "    if country == \"Norway\": country = \"挪威\" \n",
    "    if country == \"Switzerland\": country = \"捷克\" \n",
    "    if country == \"Luxembourg\": country = \"卢森堡\" \n",
    "    plt.annotate(country, xy=(pos_data_x, pos_data_y), xytext=pos_text,\n",
    "            arrowprops=dict(facecolor='black', width=0.5, shrink=0.1, headwidth=5))\n",
    "    plt.plot(pos_data_x, pos_data_y, \"rs\")\n",
    "\n",
    "X=np.linspace(0, 110000, 1000)\n",
    "plt.plot(X, t0 + t1*X, \"b:\")\n",
    "\n",
    "lin_reg_full = linear_model.LinearRegression()\n",
    "Xfull = np.c_[full_country_stats[\"人均GDP\"]]\n",
    "yfull = np.c_[full_country_stats[\"生活满意度\"]]\n",
    "lin_reg_full.fit(Xfull, yfull)\n",
    "\n",
    "t0full, t1full = lin_reg_full.intercept_[0], lin_reg_full.coef_[0][0]\n",
    "X = np.linspace(0, 110000, 1000)\n",
    "plt.plot(X, t0full + t1full * X, \"k\")\n",
    "\n",
    "save_fig('representative_training_data_scatterplot')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "051a5b91",
   "metadata": {},
   "outputs": [],
   "source": [
    "full_country_stats.plot(kind='scatter', x=\"人均GDP\", y='生活满意度', figsize=(8,3))\n",
    "plt.axis([0, 110000, 0, 10])\n",
    "\n",
    "from sklearn import preprocessing\n",
    "from sklearn import pipeline\n",
    "\n",
    "poly = preprocessing.PolynomialFeatures(degree=30, include_bias=False)\n",
    "scaler = preprocessing.StandardScaler()\n",
    "lin_reg2 = linear_model.LinearRegression()\n",
    "\n",
    "pipeline_reg = pipeline.Pipeline([('poly', poly), ('scal', scaler), ('lin', lin_reg2)])\n",
    "pipeline_reg.fit(Xfull, yfull)\n",
    "curve = pipeline_reg.predict(X[:, np.newaxis])\n",
    "plt.plot(X, curve)\n",
    "plt.xlabel(\"GDP per capita (USD)\")\n",
    "save_fig('overfitting_model_plot')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
